import argparse

from mmcv import Config
from mmcv.cnn import get_model_complexity_info

from mmseg.models import build_segmentor
from models import *

import torch
from gpu_mem_track import MemTracker
# from torchprofile import profile_macs


def parse_args():
    parser = argparse.ArgumentParser(description='Train a segmentor')
    parser.add_argument('config', help='train config file path')
    parser.add_argument(
        '--shape',
        type=int,
        nargs='+',
        default=[2048, 1024],
        help='input image size')
    parser.add_argument('--gpu_id', type=int, default=0, help='device(gpu) id')
    parser.add_argument('--batch_size', type=int, default=64, help='batch size')
    args = parser.parse_args()
    return args

def main():

    args = parse_args()
    device = torch.device(f'cuda:{args.gpu_id}')
    torch.cuda.set_device(device)
    if len(args.shape) == 1:
        input_shape = (3, args.shape[0], args.shape[0])
    elif len(args.shape) == 2:
        input_shape = (3, ) + tuple(args.shape)
    else:
        raise ValueError('invalid input shape')

    cfg = Config.fromfile(args.config)
    cfg.model.pretrained = None
    model = build_segmentor(
        cfg.model,
        train_cfg=cfg.get('train_cfg'),
        test_cfg=cfg.get('test_cfg'))#.cuda()
    # model.eval()

    if hasattr(model, 'forward_dummy'):
        model.forward = model.forward_dummy
    else:
        raise NotImplementedError(
            'FLOPs counter is currently not currently supported with {}'.
            format(model.__class__.__name__))

    gpu_tracker = MemTracker()
    
    gpu_tracker.track()
    print('load data ..')
    inputs = torch.rand([args.batch_size] + list(input_shape)).cuda()
    gpu_tracker.track()
    print('load model ..')
    model = model.cuda()
    gpu_tracker.track()

    print('training memory consumption')
    model.train()
    out = model(inputs)
    out.mean().backward()
    gpu_tracker.track()

    torch.cuda.empty_cache()
    print('inference memory consumption')
    model.eval()
    out = model()
    gpu_tracker.track()


if __name__ == '__main__':
    main()
